package com.xw.bo.ks.service.impl;

import com.alibaba.fastjson2.JSON;
import com.xw.bo.ks.entity.UserRegisterInfo;
import com.xw.bo.ks.entity.webSocket.SessionInfo;
import com.xw.bo.ks.service.UserRegisterInfoService;
import com.xw.bo.ks.service.WebSocketUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.websocket.Session;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author： XW -> ~
 * @create： 2024/6/28 11:45
 */
@Slf4j
@Service
public class WebSocketUserServiceImpl implements WebSocketUserService {

    /**
     * key=userId。一个userId只维持一个Session
     */
    private Map<String, Session> homeMap = new HashMap<>();

    // key=userId
    private Map<String, SessionInfo> sessionMap = new HashMap<>();

    /**
     * key=sessionId value=userId
     * 一个sessionId，只对于一个userId
     */
    private Map<String, String> sessionIdMap = new HashMap<>();

    @Resource
    private UserRegisterInfoService userRegisterInfoService;


    @Override
    public void onOpen(String friendId, String accessKey, Session session) {
        // 连接打开时的逻辑
        log.info("onOpen id = {}", session.getId());
        log.info("onOpen home = {}", friendId);
        log.info("onOpen Accesskey = {}", accessKey);

        UserRegisterInfo userInfo = userRegisterInfoService.getUserInfo(accessKey);
        if (userInfo == null) {
            log.info("用户还没有登录，不能进行session连接");
            return;
        }
        String userId = userInfo.getUserId().toString();

        if (homeMap.containsKey(userId)) {
            Session oldSession = homeMap.get(userId);
            if (!session.getId().equals(oldSession.getId())) {
                try {
                    oldSession.close();
                } catch (IOException e) {
                    log.error("关闭socket失败，userId = {}",userId);
                }
                sessionIdMap.remove(oldSession.getId());
            }
        }
        sessionIdMap.put(session.getId(), userId);

        SessionInfo sessionInfo = new SessionInfo();
        sessionInfo.setSessionId(session.getId());
        sessionInfo.setAccessKey(accessKey);
        sessionInfo.setFriendId(friendId);
        sessionInfo.setUserId(userId);

        sessionMap.put(userId, sessionInfo);
        homeMap.put(userId, session);


        log.info("homeMap = {}", homeMap.hashCode());
        log.info("homeMap = {}", homeMap.get(friendId));
        log.info("sessionMap = {}", JSON.toJSONString(sessionMap));
    }

    @Override
    public void onClose(Session session) {
        // 连接关闭时的逻辑
        String userId = sessionIdMap.get(session.getId());
        if (StringUtils.isEmpty(userId)) {
            log.info("userId为空");
            return;
        }

        SessionInfo sessionInfo = sessionMap.get(userId);
        if (sessionInfo == null) {
            log.info("sessionInfo为空");
            return;
        }

        sessionMap.remove(userId);
        sessionIdMap.remove(session.getId());

        Session oldSession = homeMap.get(sessionInfo.getUserId());
        if (oldSession == null) {
            log.info("oldSession为空");
            return;
        }
        if (!Objects.equals(oldSession.getId(), session.getId())) {
            log.info("sessionId没有对接上");
            return;
        }
        homeMap.remove(sessionInfo.getUserId());
    }

    @Override
    public void onMessage(String message, Session session) {

        // 连接关闭时的逻辑
        String userId = sessionIdMap.get(session.getId());
        if (StringUtils.isEmpty(userId)) {
            log.info("accessKey为空");
            return;
        }

        SessionInfo sessionInfo = sessionMap.get(userId);
        if (sessionInfo == null) {
            log.info("sessionInfo为空");
            return;
        }

        Session friendSession = homeMap.get(sessionInfo.getFriendId());
        if (friendSession == null) {
            log.info("对方还没有连接，暂时不能通信！！");
            return;
        }

        // 接收到消息时的逻辑
        log.info("message = {}", message);
        try {
            friendSession.getBasicRemote().sendText(message);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        log.info("message sessionMap = {}", JSON.toJSONString(sessionMap));

    }

}
